from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from book.models import BookInfo
from book.modelserializer import BookModelSerialzier


class BooksView(GenericAPIView):
    # GenericAPIView和APIView使用区别 指定两个属性
    # 序列化器属性
    serializer_class = BookModelSerialzier
    # 查询集属性
    queryset = BookInfo.objects.all()

    def post(self, request):
        data_dict = request.data
        # 使用self.get_serializer获取serializer_class属性所指定的序列化器，进行初始化操作，初始化数据通过方法传递参数
        ser = self.get_serializer(data=data_dict)

        try:
            ser.is_valid(raise_exception=True)
        except:
            return Response({'error': ser.errors})
        ser.save()
        data = ser.data
        return Response(data)

    def get(self, request):
        """
            获取所有图书
        :param request:
        :return:
        """
        # 查询数据库获取所有图书
        # self.get_queryset()获取queryset所保存的所有查询集数据
        books = self.get_queryset()
        # 返回结果
        ser = self.get_serializer(books)
        book_list = ser.data
        return Response({'book_list': book_list})


class BookView(GenericAPIView):
    # 指定序列化器属性
    serializer_class = BookModelSerialzier
    # 指定查询集属性
    queryset = BookInfo.objects.all()

    def get(self, request, pk):
        """
            获取单一图书
        :param request:
        :return:
        """
        # 1、根据id值查询数据库
        try:
            # self.get_object()方法从queryset属性所指定的查询集中，会根据参数pk值也就是id匹配到对应的数据对象
            book = self.get_object()
        except:
            return Response({'error': 'id不存在'}, status=400)

        ser = self.get_serializer(book)
        return Response(ser.data)

    def put(self, request, pk):
        """
            更新图书
        :param request:
        :return:
        """
        # 1、获取前端数据
        data_dict = request.data
        # 2、验证数据  更新数据时，序列化器初始化除了传递验证的字典数据外，还需要传递更新的数据对象
        book = BookInfo.objects.get(id=pk)
        ser = BookModelSerialzier(book, data=data_dict)
        try:
            ser.is_valid(raise_exception=True)
        except:
            return Response({'error': ser.errors})

        # 3、验证成功，更新数据
        ser.save()

        # 4、返回结果
        return Response(ser.data)

    def delete(self, request, pk):
        """
              删除图书
          :param request:
          :return:
         """
        # 1、根据id值查询数据库,获取删除的图书
        try:
            book = BookInfo.objects.get(id=pk)
        except:
            return Response({'error': 'id不存在'}, status=400)

        # 2、删除图书  逻辑删除 物理删除
        # book.delete()# 物理删除
        book.is_delete = True
        book.save()
        return Response({})
